home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 592b.lha / TermII / English / XCMD Examples / XCMDLaser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-22  |  9.3 KB  |  421 lines

  1. /*
  2. *   XCMDLaser
  3. *
  4. *       XCMD for Term II, allowing the download of PostScript files to
  5. *       an Apple Laser Writer. We are using some functions of the
  6. *       Laser Writer :
  7. *
  8. *           - a ^D must be sent at the end of each file
  9. *           - the printer send a ^D when current job is
  10. *             finished, and a new file can be processed
  11. *
  12. *       To compile with DICE :
  13. *
  14. *           dcc XCMDTools.o XCMDLaser.c -o XCMDLaser
  15. *
  16. */
  17.  
  18. #include <exec/types.h>
  19. #include <exec/memory.h>
  20. #include <intuition/intuition.h>
  21. #include <libraries/gadtools.h>
  22. #include <clib/exec_protos.h>
  23. #include <clib/dos_protos.h>
  24. #include <clib/asl_protos.h>
  25. #include <clib/intuition_protos.h>
  26. #include <clib/gadtools_protos.h>
  27. #include <clib/graphics_protos.h>
  28. #include <clib/alib_protos.h>
  29. #include <string.h>
  30. #include <stdio.h>
  31. #include "XCMD.h"
  32. #include "XCMDtools.h"
  33.  
  34.  
  35.  
  36. /*
  37. *   DEFINE
  38. */
  39. #define BUF_SIZE 80
  40. #define BOX 50
  41. #define TIMEOUT_LIMIT 180     /* in seconds */
  42.  
  43. /*
  44. *   VARIABLES
  45. */
  46. struct MsgPort *port = NULL;
  47. struct XCMD *XCMD = NULL;
  48. FILE *fp = NULL;
  49. const char PRINTER_EOF  = '\x04';
  50. const char INTERRUPT    = '\x03';
  51. const char STATUS_QUERY = '\x14';
  52. struct FileRequester *FileRequester = NULL;
  53. struct AslBase *AslBase = NULL;
  54. struct Library *GadToolsBase = NULL;
  55. struct IntuitionBase *IntuitionBase = NULL;
  56. struct GadgetList *glist = NULL;
  57. struct Window *window = NULL;
  58. struct Screen *screen = NULL;
  59. void *vi = NULL;
  60. struct Gadget *GadName, *GadStop;;
  61. struct TextAttr Topaz80 = { "topaz.font",8,0,0 };
  62.  
  63. /*
  64. *   PROTOS
  65. */
  66. void End(char *);
  67. void DownloadFile(char *);
  68. void ExecuteXCMD(char *, void *, void *, void *);
  69. void InitIntuition(void);
  70. long FileSize(char *);
  71. void HandleIntuition(void);
  72. void UpdateBox(long,long);
  73. void exit(int);
  74.  
  75. /*
  76. *   MAIN
  77. */
  78. int main(int argc, char *argv[])
  79.   {
  80.  
  81.   char buffer_name[256];
  82.  
  83.   /*
  84.   *  Allocate and initialize ressources
  85.   */
  86.   if(!FindPort("TERM"))
  87.     End("I can't find Term II");
  88.   port = CreatePort("LASER",0);
  89.   if(!port)
  90.     End("I can't create my message port");
  91.   XCMD = CreateXCMD(port);
  92.   if(!XCMD)
  93.     End("I can't create the XCMD");
  94.   AslBase = OpenLibrary(AslName,36);
  95.   if(!AslBase)
  96.     End("I can't find library asl v36 or above");
  97.   struct FileRequester *FileRequester = AllocAslRequest(ASL_FileRequest,NULL);
  98.   if(!FileRequester)
  99.     End("I can't create a file requester");
  100.   InitIntuition();
  101.  
  102.  
  103.   /*
  104.   *  Get files and print them
  105.   */
  106.   if(AslRequestTags(FileRequester,ASL_FuncFlags,FILF_MULTISELECT|FILF_PATGAD,
  107.     ASL_Pattern,(ULONG)"#?",
  108.     ASL_Hail,(ULONG)"Multiselect",
  109.     TAG_DONE))
  110.     {
  111.     int nb_files = FileRequester->rf_NumArgs;
  112.     if(nb_files)
  113.       {
  114.       struct WBArg *wb_arg = FileRequester->rf_ArgList;
  115.       while(nb_files--)
  116.         {
  117.         NameFromLock(wb_arg->wa_Lock,buffer_name,256);
  118.         AddPart(buffer_name,wb_arg->wa_Name,256);
  119.         DownloadFile(buffer_name);
  120.         wb_arg++;
  121.         }
  122.       }
  123.     else
  124.       {
  125.       if(FileRequester->rf_File[0] != '\0')
  126.         {
  127.         strcpy(buffer_name,FileRequester->rf_Dir);
  128.         AddPart(buffer_name,FileRequester->rf_File,256);
  129.         DownloadFile(buffer_name);
  130.         }
  131.       }
  132.     }
  133.   End("Done");
  134.   }
  135.  
  136.  
  137.  
  138.  
  139. /*
  140. *   void End(char *message)
  141. *
  142. *       End program and free ressources
  143. */
  144. void End(char *message)
  145.   {
  146.   puts(message);
  147.   if(XCMD)      /* This to be sure to make Term II read the serial port */
  148.     {
  149.     /*
  150.     *   We don't use ExecuteXCMD(), for in case of
  151.     *   error we'll be back here for an infinite loop
  152.     */
  153.     XCMD->xcmd_Command = "serial_on";
  154.     if(SendXCMD(XCMD))
  155.       {
  156.       WaitPort(port);
  157.       GetMsg(port);
  158.       }
  159.     }
  160.   if(fp) fclose(fp);
  161.   if(XCMD) DeleteXCMD(XCMD);
  162.   if(port) DeletePort(port);
  163.   if(FileRequester) FreeAslRequest(FileRequester);
  164.   if(AslBase) CloseLibrary(AslBase);
  165.   if(window)
  166.     {
  167.     struct IntuiMessage *msg;
  168.     while(msg = GT_GetIMsg(window->UserPort)) GT_ReplyIMsg(msg);
  169.     CloseWindow(window);
  170.     }
  171.   if(vi) FreeVisualInfo(vi);
  172.   if(glist) FreeGadgets(glist);
  173.   if(screen) UnlockPubScreen(NULL,screen);
  174.   if(GadToolsBase) CloseLibrary(GadToolsBase);
  175.   if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  176.   exit(0);
  177.   }
  178.  
  179.  
  180.  
  181. /*
  182. *   void DownloadFile(char *filename)
  183. *
  184. *       Download the file whose name is filename
  185. */
  186. void DownloadFile(char *filename)
  187.   {
  188.   unsigned char write_buffer[BUF_SIZE];
  189.   char intui_buffer[60];
  190.   long file_size = FileSize(filename);
  191.   long size = 0;
  192.   sprintf(intui_buffer,"Downloading %s (%d bytes)",FilePart(filename),file_size);
  193.   GT_SetGadgetAttrs(GadName,window,NULL,GTTX_Text,intui_buffer,TAG_DONE);
  194.   fp = fopen(filename,"r");
  195.   if(!fp)
  196.     End("I can't open file");
  197.   char c;
  198.   int i = 0;
  199.   while((c=getc(fp)) != EOF)
  200.     {
  201.     write_buffer[i] = c;
  202.     i++;
  203.     if(i == BUF_SIZE)
  204.       {
  205.       ExecuteXCMD("xcmd_swrite",write_buffer,(void *)BUF_SIZE,NULL);
  206.       size += BUF_SIZE;
  207.       HandleIntuition();
  208.       UpdateBox(size,file_size);
  209.       i = 0;
  210.       }
  211.     }
  212.   if(i>0)
  213.     ExecuteXCMD("xcmd_swrite",write_buffer,(void *)i,NULL);
  214.   /*
  215.   *  We get sure Term II will read chars only when we
  216.   *  ask for it.
  217.   */
  218.   ExecuteXCMD("serial_off",NULL,NULL,NULL);
  219.   ExecuteXCMD("xcmd_swrite",&PRINTER_EOF,(void *)1,NULL);
  220.   size+=i;
  221.   UpdateBox(size,file_size);
  222.   /*
  223.   *     Wait for a ^D. See time out value
  224.   */
  225.   BOOL not_the_end = TRUE;
  226.   while(not_the_end)
  227.     {
  228.     HandleIntuition();
  229.     int i;
  230.     for(i=0; i<TIMEOUT_LIMIT; i++)
  231.       {
  232.       char eof;
  233.       ExecuteXCMD("xcmd_sread",&eof,(void *)1,(void *)1000000);
  234.       if(((long)XCMD->xcmd_Args[15])>0)
  235.         {
  236.         if(eof == PRINTER_EOF)
  237.           {
  238.           not_the_end = FALSE;
  239.           break;
  240.           }
  241.         }
  242.       HandleIntuition();
  243.       }
  244.     if(not_the_end) End("No answer from printer");
  245.     }
  246.   ExecuteXCMD("serial_on",NULL,NULL,NULL);
  247.   fclose(fp); fp = NULL;
  248.   GT_SetGadgetAttrs(GadName,window,NULL,GTTX_Text,NULL,TAG_DONE);
  249.   SetAPen(window->RPort,(UBYTE)0);
  250.   RectFill(window->RPort,BOX+4,58,BOX+4+242,70);
  251.   SetAPen(window->RPort,(UBYTE)3);
  252.   }
  253.  
  254.  
  255.  
  256.  
  257. /*
  258. *   void ExecuteXCMD()
  259. *
  260. *       Execute an XCMD and wait for an answer. Quit in case of
  261. *       error.
  262. */
  263. void ExecuteXCMD(char *command, void *arg1, void *arg2, void *arg3)
  264.   {
  265.   if(!XCMD) End("No XCMD !");
  266.   XCMD->xcmd_Command = command;
  267.   XCMD->xcmd_Args[0] = arg1;
  268.   XCMD->xcmd_Args[1] = arg2;
  269.   XCMD->xcmd_Args[2] = arg3;
  270.   if(SendXCMD(XCMD))
  271.     {
  272.     WaitPort(port);
  273.     GetMsg(port);
  274.     }
  275.   else
  276.     End("SendXCMD() failed");
  277.   }
  278.  
  279.  
  280.  
  281. /*
  282. * void InitIntuition()
  283. *
  284. *       Init intuition
  285. */
  286. void InitIntuition()
  287.   {
  288.   ExecuteXCMD("xcmd_lock_request",NULL,NULL,NULL);
  289.   screen = XCMD->xcmd_TermScreen;
  290.   UnLock(XCMD->xcmd_TermDir);
  291.  
  292.   IntuitionBase = OpenLibrary("intuition.library",36);
  293.   if(!IntuitionBase)
  294.     End("No intuition.library v36 or above");
  295.  
  296.   GadToolsBase = OpenLibrary("gadtools.library",36);
  297.   if(!GadToolsBase)
  298.     End("No gadtools.library v36 or above");
  299.  
  300.   vi = GetVisualInfo(screen, TAG_DONE);
  301.   if(!vi)
  302.     End("I can't get visual info");
  303.  
  304.   window = OpenWindowTags(NULL,
  305.     WA_Top, 20,
  306.     WA_Left, 15,
  307.     WA_DragBar, TRUE,
  308.     WA_DepthGadget, TRUE,
  309.     WA_PubScreen, screen,
  310.     WA_Width, 350,
  311.     WA_Height, 120,
  312.     WA_IDCMP, REFRESHWINDOW|TEXTIDCMP|BUTTONIDCMP,
  313.     WA_Title, "Downloading PostScript files (v1.0)",
  314.     WA_Activate, TRUE,
  315.     TAG_DONE);
  316.   if(!window)
  317.     End("I can't open the window");
  318.  
  319.   struct Gadget *gad = CreateContext(&glist);
  320.   struct NewGadget ng;
  321.  
  322.   ng.ng_TextAttr = &Topaz80;
  323.   ng.ng_VisualInfo = vi;
  324.   ng.ng_LeftEdge = 10;
  325.   ng.ng_TopEdge = 30;
  326.   ng.ng_Width = 260;
  327.   ng.ng_Height = 10;
  328.   ng.ng_Flags = 0;
  329.   ng.ng_GadgetText = NULL;
  330.   gad = GadName = CreateGadget(TEXT_KIND,gad,&ng,TAG_DONE);
  331.  
  332.   ng.ng_TopEdge += 60;
  333.   ng.ng_LeftEdge = 130;
  334.   ng.ng_Height = 14;
  335.   ng.ng_Width = 100;
  336.   ng.ng_GadgetText = "STOP";
  337.   gad = GadStop = CreateGadget(BUTTON_KIND,gad,&ng,TAG_DONE);
  338.  
  339.   if(!gad)
  340.     End("I can't create gadgets");
  341.  
  342.   AddGList(window,glist,-1,-1,NULL);
  343.   RefreshGList(glist,window,NULL,-1);
  344.   GT_RefreshWindow(window,NULL);
  345.  
  346.   DrawBevelBox(window->RPort,BOX,55,250,20,GT_VisualInfo,vi,GTBB_Recessed,TRUE,TAG_DONE);
  347.   }
  348.  
  349. /*
  350. * void HandleIntuition()
  351. *
  352. *       Handle Intuition events
  353. */
  354. void HandleIntuition()
  355.   {
  356.   struct IntuiMessage *msg;
  357.   BOOL stop = FALSE;
  358.   while(msg = GT_GetIMsg(window->UserPort))
  359.     {
  360.     ULONG class = msg->Class;
  361.     struct Gadget *gadget = msg->IAddress;
  362.     GT_ReplyIMsg(msg);
  363.     switch(class)
  364.       {
  365.       case GADGETUP :
  366.         if(gadget == GadStop)
  367.           stop = TRUE;
  368.         break;
  369.       case REFRESHWINDOW :
  370.         GT_BeginRefresh(window);
  371.         GT_EndRefresh(window,TRUE);
  372.         break;
  373.       default:
  374.         break;
  375.       }
  376.     }
  377.   if(stop)
  378.     {
  379.     ExecuteXCMD("xcmd_swrite",&INTERRUPT,(void *)1,NULL);
  380.     End("Stop by user");
  381.     }
  382.   }
  383.  
  384. /*
  385. * long FileSize(char *)
  386. *
  387. *   Return size in bytes of a file
  388. */
  389. long FileSize(char *filename)
  390.   {
  391.   BPTR lock = Lock(filename,ACCESS_READ);
  392.   long size = 0;
  393.   if(lock)
  394.     {
  395.     struct FileInfoBlock *fib = AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR|MEMF_PUBLIC);
  396.     if(fib)
  397.       {
  398.       Examine(lock,fib);
  399.       size = fib->fib_Size;
  400.       FreeMem(fib,sizeof(struct FileInfoBlock));
  401.       }
  402.     UnLock(lock);
  403.     }
  404.   return(size);
  405.   }
  406.  
  407.  
  408. /*
  409. * void UpdateBox(long current, long size)
  410. *
  411. *   Update the box reflecting current status of downloading.
  412. *       current = nb of bytes already downloaded
  413. *       size    = nb of bytes to download
  414. */
  415. void UpdateBox(long current, long size)
  416.   {
  417.   long width = (242 * current) / size;
  418.   RectFill(window->RPort,BOX+4,58,BOX+width+4,70);
  419.   }
  420.  
  421.